import GBK from './charset/gbk.js'
let requestTasks = [];

//xhr封装
function xhrRequest (type = 'GET', url, options) {
	return new Promise((resolve,reject) => {
		// #ifdef H5
		let xhrHttp = new XMLHttpRequest();
		// #endif
		// #ifdef APP
		let xhrHttp = new plus.net.XMLHttpRequest();
		// #endif
		let d = new Date();
		let taskId = options.taskId || (d.getMinutes().toString() + d.getSeconds() + d.getMilliseconds() + Math.round(Math.random() * 10000))
		requestTasks.push({
			id: taskId,
			request: xhrHttp
		})
		try {
			xhrHttp.onreadystatechange = function () {
				// console.log(xhrHttp.readyState);
				if ( xhrHttp.readyState == 4 ) {
					if ( xhrHttp.status == 200 ) {
						resolve({code: xhrHttp.status, data: xhrHttp.responseText})
					} else {
						// plus.nativeUI.toast("网络错误！", {verticalAlign: 'bottom'});
						reject({code: xhrHttp.status, data: ''});
					}
					xhrHttp.abort()
				}
			}
			xhrHttp.onabort = function () {
				let index = requestTasks.findIndex(task => task.id == taskId)
				index > -1 ? requestTasks.splice(index, 1) : null
				xhrHttp = null
				reject({"errMsg":"request:fail abort"});
			}
			xhrHttp.open(type, url);
			if ( options.mimeType ) {
				xhrHttp.overrideMimeType(options.mimeType);
			}
			xhrHttp.responseType = options.responseType || 'json';
			Object.keys(options.headers || {}).forEach(key => {
				xhrHttp.setRequestHeader(key, options.headers[key]);
			})
			xhrHttp.timeout = options.timeout || 30000;
			xhrHttp.send(param(options.params || {}, options.headers?.Charset || 'utf-8'));
		} catch (e) {
			xhrHttp.abort()
			reject({code: xhrHttp.status, data: ''});
		}
	})
}

export default class Xhr {
	get(url, options = {}) {
		return xhrRequest('GET', urlPrams(url, options), options)
	}
	postget(url, options = {}) {
		return xhrRequest('POST', urlPrams(url, options), options)
	}
	post(url, options = {}) {
		return xhrRequest('POST', url, options)
	}
	getAll(reqs) {
		return Promise.all(
			reqs.map(req => {
				return this.get(urlPrams(req.url, req.options), req?.options || {})
			})
		)
	}
	postgetAll(reqs) {
		return Promise.all(
			reqs.map(req => {
				return this.postget(urlPrams(req.url, req.options), req?.options || {})
			})
		)
	}
	postAll(reqs) {
		return Promise.all(
			reqs.map(req => {
				return this.post(req.url, req?.options || {})
			})
		)
	}
	abort(taskIds) {
		taskIds.split(',').forEach(taskId => {
			let index = requestTasks.findIndex(task => task.id == taskId)
			if ( index > -1 ) {
				requestTasks[index].request.abort()
			} else {
				throw new Error('The requested task with taskid ' + taskId + ' is not defined')
			}
		})
	}
}

function param(data, charset = 'utf-8') {
    let url = ''
	let params = charsetParams(data, charset)
    for (var k in params) {
        let value = params[k] !== undefined ? params[k] : ''
        url += `&${k}=${ charset == 'utf-8' ? encodeURIComponent(value) : value}`
    }
    return url ? url.substring(1) : ''
}

function urlPrams (url, options = {}) {
	url += (url.indexOf('?') < 0 ? '?' : '&') + param(options.params || {}, options.headers?.Charset || 'utf-8') || ''
    return url
}

function charsetParams (params, charset = 'utf-8') {
	Object.keys(params).forEach(key => {
		params[key] = (charset == 'utf-8' || charset == 'UTF-8') ? params[key] : (charset.indexOf('gb') > -1 || charset.indexOf('GB') > - 1) ? GBK(params[key]) : params[key]
	})
	return params
}